<?php
/**
 *title
 * @author: lican<364548233@qq.com>
 *Date: 2021/1/8
 *Time: 16:57
 */

namespace App\Http\Services;

use App\Http\Helpers\Http;
use App\Http\Helpers\Sign;
use App\Models\School;
use App\Models\Stu;
use App\Models\Role;

class ApiService{

    const APP_KEY = "3ECB921B4DE43DAD";
    const APP_SECRET = "6610B66329EB252D80CCC108167B52DE";
    const WX_UNI_DOMAIN = "https://uni.weixiao.qq.com";
    const OPEN_WECARD_DOMAIN = "https://open.wecard.qq.com";

    const PC_OAUTH = "/connect/oauth/pc-authorize";
    const H5_OAUTH = "/connect/oauth/authorize";
    const OAUTH_TOKEN = "/connect/oauth2/token";
    const USERINFO = "/connect/oauth/get-user-info";
    const ROLE_RULE = '/cgi-bin/permission/user-permission';

    const ACCESS_TOKEN = "/cgi-bin/oauth2/token";
    const SCHOOL_INFO = "/cgi-bin/campus/school-info";

    const OLD_AUTH_TOKRN = "https://uni.weixiao.qq.com/open/cgi-bin/access-token"; //旧版登录token
    const OLD_MANAGER_INFO = "https://uni.weixiao.qq.com/open/cgi-bin/get-manager-info"; //旧版管理员信息

    /**
     *消息通知
     * @author: lican<364548233@qq.com>
     */
    public static function sendNotice($schoolCode, $cards, $title, $content, $sender, $customs = null){
        $params = [
            'access_token' => ApiService::getAccessToken($schoolCode),
            'cards' => json_encode($cards),
            'title' => $title,
            'content' => $content,
            'sender' => $sender,
            'digest' => '查看管理员回复',
        ];
        if (isset($customs)) {
            $params['customs'] = is_array($customs) ? json_encode($customs) : $customs;
        }
        $school = SchoolService::getSchoolInfo($schoolCode);
        $localHost = $school['gate_host'] ?? 'https://open.wecard.qq.com';
        $url =  $localHost .'/cgi-bin/notice/send';
        $http = new Http();
        $result = $http->post($url, $params);
        Sign::writeLog("给".json_encode($cards, true)."发通知结果：", $result, 'notice');
        if(!isset($result['code']) || $result['code'] != 0) {
            Sign::writeLog("通知发放失败：", $result, 'notice');
            return MsgService::getMsg(3003);
        }
        return MsgService::getMsg(0, ['mark' => $result['mark']]);
    }

    /**
     *获取微校管理员权限
     * @author lican<364548233@qq.com>
     */
    public static function getManageRule($schoolCode, $cardNumber){
        $url = self::OPEN_WECARD_DOMAIN . self::ROLE_RULE;
        $params = [
            'access_token' => self::getAccessToken($schoolCode),
            'card_number' => $cardNumber
        ];
        $http = new Http();
        $res = $http->post($url, $params);
        $rule = $res['data'];
        if($rule['super_manager']){
            $role = Role::ADMIN;
        }elseif($rule['manager']){
            $role = Role::DEFAULT;
        }else{
            $role = Role::DEFAULT;
        }
        return $role;
    }

    /**
     *获取用户信息
     * @author lican<364548233@qq.com>
     */
    public static function getUserInfo($accessToken, $schoolInfo){
        $params = [
            'access_token' => $accessToken
        ];
        $domain = $schoolInfo['gate_host'];
        $url = $domain . self::USERINFO;
        $http = new Http();
        $res = $http->post($url, $params);
//        $schoolCode = $res['ocode'];
//        $schoolInfo = SchoolService::getSchoolInfo($schoolCode);

        $update = [
            'weixiao_stu_id' => isset($res['weixiao_stu_id']) ? $res['weixiao_stu_id'] : '',
            'name' => $res['name'],
            'identity_type' => $res['identity_type'],
            'grade' => isset($res['grade']) ? $res['grade'] : 0,
            'college' => isset($res['college']) ? $res['college'] : '',
            'profession' => isset($res['profession']) ? $res['profession'] : '',
            'class' => isset($res['class']) ? $res['class'] : '',
            'identity_title' => isset($res['identity_title']) ? $res['identity_title'] : '',
            'gender' => isset($res['gender']) ? $res['gender'] : 0,
            'head_image' => isset($res['head_image']) ? $res['head_image'] : '',
            'organization' => isset($res['organization']) ? implode(',', $res['organization']) : '',
            'role' => isset($res['role']) ? implode('', $res['role']) : '',
            'campus' => isset($res['campus']) ? $res['campus'] : '',
            'dorm_number' => isset($res['dorm_number']) ? $res['dorm_number'] : '',
            'physical_card_number' => isset($res['physical_card_number']) ? $res['physical_card_number'] : '',
            'physical_chip_number' => isset($res['physical_chip_number']) ? $res['physical_chip_number'] : '',
            'nation' => isset($res['nation']) ? $res['nation'] : '',
            'birthday' => isset($res['birthday']) ? $res['birthday'] : '',
            'origin_place' => isset($res['origin_place']) ? $res['origin_place'] : '',
            'graduated_school' => isset($res['graduated_school']) ? $res['graduated_school'] : '',
            'address' => isset($res['address']) ? $res['address'] : '',
//                    'contract_person' => isset($res['contract_person']) ? $res['contract_person'] : '',
//                    'contract_phone' => isset($res['contract_phone']) ? $res['contract_phone'] : '',
            'email' => isset($res['email']) ? $res['email'] : '',
            'id_card' => isset($res['id_card']) ? $res['id_card'] : '',
            'telephone' => isset($res['telephone']) ? $res['telephone'] : '',
            'start_at' => isset($res['start_at']) ? $res['start_at'] : '',
            'expire_at' => isset($res['end_at']) ? $res['end_at'] : '',
            'active_status' => isset($res['active_status']) ? $res['active_status'] : 0,
            'entrust_status' => isset($res['entrust_status']) ? $res['entrust_status'] : 0,
            'frozen_status' => isset($res['frozen_status']) ? $res['frozen_status'] : 0,
            'bind_status' => isset($res['bind_status']) ? $res['bind_status'] : 0
        ];
        try{
            $stu = Stu::updateOrCreate(['school_id' => $schoolInfo['id'], 'card_number' => $res['card_number']],
                $update
            );
        }catch(\Exception $e){
            print_r($e->getMessage());die;
        }

        $res['stu_id'] = $stu->id;
        return array_only($res, ['stu_id', 'card_number', 'name', 'ocode', 'telephone', 'email']);
    }

    /**
     *旧版获取管理员信息
     * @author: lican<364548233@qq.com>
     */
    public static function getOldUserInfo($wxcode, $accessToken, $schoolInfo){
        $url = self::OLD_MANAGER_INFO;
        $arr = [
            "wxcode" => $wxcode,
            "access_token" => $accessToken
        ];
        $http = new Http();
        $user = $http->post($url, $arr);
        if($user['errcode'] == 0){
            $res = $user['manager_real_info']; //获取管理员数据
            $update = [
                'weixiao_stu_id' => isset($res['weixiao_stu_id']) ? $res['weixiao_stu_id'] : '',
                'name' => $res['name'],
                'identity_type' => $res['identity_type'],
                'grade' => isset($res['grade']) ? $res['grade'] : 0,
                'college' => isset($res['college']) ? $res['college'] : '',
                'profession' => isset($res['profession']) ? $res['profession'] : '',
                'class' => isset($res['class']) ? $res['class'] : '',
                'identity_title' => isset($res['identity_title']) ? $res['identity_title'] : '',
                'gender' => isset($res['gender']) ? $res['gender'] : 0,
                'head_image' => isset($res['head_image']) ? $res['head_image'] : '',
                'organization' => isset($res['organization']) ? implode(',', $res['organization']) : '',
                'role' => isset($res['role']) ? implode('', $res['role']) : '',
                'campus' => isset($res['campus']) ? $res['campus'] : '',
                'dorm_number' => isset($res['dorm_number']) ? $res['dorm_number'] : '',
                'physical_card_number' => isset($res['physical_card_number']) ? $res['physical_card_number'] : '',
                'physical_chip_number' => isset($res['physical_chip_number']) ? $res['physical_chip_number'] : '',
                'nation' => isset($res['nation']) ? $res['nation'] : '',
                'birthday' => isset($res['birthday']) ? $res['birthday'] : '',
                'origin_place' => isset($res['origin_place']) ? $res['origin_place'] : '',
                'graduated_school' => isset($res['graduated_school']) ? $res['graduated_school'] : '',
                'address' => isset($res['address']) ? $res['address'] : '',
//                    'contract_person' => isset($res['contract_person']) ? $res['contract_person'] : '',
//                    'contract_phone' => isset($res['contract_phone']) ? $res['contract_phone'] : '',
                'email' => isset($res['email']) ? $res['email'] : '',
                'id_card' => isset($res['id_card']) ? $res['id_card'] : '',
                'telephone' => isset($res['telephone']) ? $res['telephone'] : '',
                'start_at' => isset($res['start_at']) ? $res['start_at'] : '',
                'expire_at' => isset($res['end_at']) ? $res['end_at'] : '',
                'active_status' => isset($res['active_status']) ? $res['active_status'] : 0,
                'entrust_status' => isset($res['entrust_status']) ? $res['entrust_status'] : 0,
                'frozen_status' => isset($res['frozen_status']) ? $res['frozen_status'] : 0,
                'bind_status' => isset($res['bind_status']) ? $res['bind_status'] : 0
            ];
            try{
                $stu = Stu::updateOrCreate(['school_id' => $schoolInfo['id'], 'card_number' => $res['card_number']],
                    $update
                );
            }catch(\Exception $e){
                print_r($e->getMessage());die;
            }

            $res['stu_id'] = $stu->id;
            return array_only($res, ['stu_id', 'card_number', 'name', 'ocode', 'telephone', 'email']);
        }else{
            return [];
        }

    }

    /**
     *获取登录token
     * @author lican<364548233@qq.com>
     */
    public static function getOauthToken($wxcode, $school, $redirectUri){
        $params = [
            'wxcode' => $wxcode,
            'app_key' => self::APP_KEY,
            'app_secret' => self::APP_SECRET,
            'grant_type' => 'authorization_code',
            'redirect_uri' => $redirectUri
        ];
        $domain = $school['gate_host'] ?? "https://open.wecard.qq.com";
        $url = $domain . self::OAUTH_TOKEN;
        $http = new Http();
        $res = $http->post($url, $params);
        return isset($res['access_token']) ? $res['access_token'] : null;
    }

    /**
     *获取旧版PC登录token
     * @author: lican<364548233@qq.com>
     */
    public static function getOldAuthToken(){
        $url = self::OLD_AUTH_TOKRN;
        $arr = [
            "app_key" => "0612FFCB6BBE684C",
            "app_secret" => "33D55A52ABA82D96BD1D05E5DBA9FCC2"
        ];
        $http = new Http();
        $res = $http->post($url, $arr);
        return $res['access_token'] ?? '';
    }

    /**
     *获取主体数据
     * @author lican<364548233@qq.com>
     */
    public static function getSchoolInfo($schoolCode, $host = ApiService::OPEN_WECARD_DOMAIN){
        $url = $host.self::SCHOOL_INFO;
        $accessToken = self::getAccessToken($schoolCode);
        $params = ['access_token' => $accessToken];
        $http = new Http();
        $res = $http->post($url, $params);
        $schoolInfo = [
            'name' => $res['name'],
            'badge' => $res['badge'],
            'manage_logo' => $res['manage_logo'],
            'local_host' => $res['local_host'],
            'local_deploy' => $res['local_deploy'],
            'gate_host' => $res['gate_host']
        ];
        return MsgService::getMsg(0, ['school_info' => $schoolInfo]);
    }

    /**
     *应用获取主体token
     * @author: lican<364548233@qq.com>
     */
    public static function getAccessToken($schoolCode){
        $key = "access_token_{$schoolCode}";
        $accessToken = app('redis')->get($key);
        if(empty($accessToken)){
            $url = self::OPEN_WECARD_DOMAIN.self::ACCESS_TOKEN;
            $params = [
                'app_key' => self::APP_KEY,
                'app_secret' => self::APP_SECRET,
                'grant_type' => 'client_credentials',
                'scope' => 'base',
                'ocode' => $schoolCode
            ];
            $http = new Http();
            $result = $http->post($url, $params);
            $accessToken = $result['access_token'];
            app('redis')->setex($key, '3600', $accessToken);
        }
        return $accessToken;
    }

}
